---
layout: ../../layouts/PageLayout.astro
title: Mutations
description: Learn how to run GraphQL mutations
order: 4
---

# Mutations

## Mutations Basics

**villus** offers a `useMutation` function that is very similar to its **[querying](/queries.md)** counterpart but with few distinct differences:

- It **does not** accept a `variables` option.
- It **does not** execute automatically, you have to explicitly call `execute`.
- Cache policies do not apply to mutations as mutations represent user actions and will always use `network-only` policy.

Here is an example of the `useMutation` function:

```vue
<template>
  <div>
    <div v-if="data">
      <p>{{ data.likePost.message }}</p>
    </div>
    <button @click="execute()">Submit</button>
  </div>
</template>

<script setup>
import { useMutation } from 'villus';

const LikePost = `
  mutation {
    likePost (id: 123) {
      message
    }
  }
`;

const { data, execute } = useMutation(LikePost);
</script>
```

## Passing Variables

Since the `useMutation` function does not accept a `variables` property you can pass them to the `execute` function:

```vue
<script setup>
const LikePost = `
  mutation LikePost ($id: ID!) {
    likePost (id: $id) {
      message
    }
  }
`;

const { data, execute } = useMutation(LikePost);

function onSubmit() {
  const variables = {
    id: 123,
  };

  execute(variables);
}
</script>
```

## Clearing Tagged Queries Cache

To clear [tagged queries'](/guide/queries#tagged-queries) cache, you can specify a `clearCacheTags` option when calling `useMutation` composable:

```vue
<script setup>
const CreatePost = `
  mutation CreatePost ($title: String!) {
    createPost (title: $title) {
      id
    }
  }
`;

const GetPosts = `
  query GetPosts {
    posts {
      id
      title
    }
  }
`;

const { data } = useQuery(GetPosts, {
  tags: ['all_posts'],
});

const { execute } = useMutation(CreatePost, {
  clearCacheTags: ['all_posts'],
});

function onSubmit() {
  execute({
    title: 'hello there',
  });
}
</script>
```

This will clear all the cache entries for any queries tagged with `all_posts` when using `useQuery`. The next time they are fetched they will go straight to the network and fetch the fresh data from the server.

## Refetching queries after a mutation

Aside from clearing the cache for tagged queries, you can also refetch them. By specifying `refetchTags` option when calling `useMutation` composable:

```vue
<script setup>
const CreatePost = `
  mutation CreatePost ($title: String!) {
    createPost (title: $title) {
      id
    }
  }
`;

const GetPosts = `
  query GetPosts {
    posts {
      id
      title
    }
  }
`;

const { data } = useQuery(GetPosts, {
  tags: ['all_posts'],
});

const { execute } = useMutation(CreatePost, {
  refetchTags: ['all_posts'],
});

function onSubmit() {
  execute({
    title: 'hello there',
  });
}
</script>
```

After the mutation execution completes, it will trigger a refetch for all queries tagged with `all_posts` tag. Note that `refetchTags` also clear the cache if present for those tagged queries, so the refetch will always override the network policy and the cached results.

## Handling Errors

You can handle errors by either grabbing the `error` ref returned from the `useMutation` function or by checking the result of the `execute` promise, the latter is preferable as it makes more sense in most situations. The `execute` function doesn't throw and collects all encountered errors into a `CombinedError` instance that contains any GraphQL or network errors encountered.

```vue
<script setup>
const LikePost = `
  mutation LikePost ($id: ID!) {
    likePost (id: $id) {
      message
    }
  }
`;

const { data, execute } = useMutation(LikePost);
const variables = {
  id: 123,
};

function onSubmit() {
  execute(variables).then(result => {
    if (result.error) {
      // Do something
    }
  });
}
</script>
```

## Event hooks

useMutation returns event hooks allowing you to execute code when a specific event occurs.

### onData

This is called whenever a new result is available.

```vue
<script setup>
import { useMutation } from 'villus';

const { data, execute } = useMutation(LikePost, {
  onData: (data) => {
    // Do something
    console.log(data)
  },
});
</script>
```

### onError

It is triggered when an error occurs.

```vue
<script setup>
import { useMutation } from 'villus';

const { data, execute } = useMutation(LikePost, {
  onError: (error) => {
    // Handle the error
    console.log(error)
  },
});
</script>
```

There are more things you can do with mutations, like displaying progress for users. Check the API documentation for [useMutation](/api/use-mutation).
